package com.zmn.oms.third.eliao.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zmn.base.channel.common.dro.ChannelDRO;
import com.zmn.base.channel.common.query.ChannelQuery;
import com.zmn.base.channel.dubbo.interfaces.channel.ChannelListRemoteService;
import com.zmn.base.common.data.common.dro.area.AreaDRO;
import com.zmn.base.common.data.dubbo.interfaces.area.AreaListRemoteService;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.dictionary.GlobalDict;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.phone.PhoneCity;
import com.zmn.common.phone.PhoneCityUtils;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.common.utils.string.StringUtil;
import com.zmn.consts.GateTypeConsts;
import com.zmn.manager.redis.RedisManager;
import com.zmn.mcc.common.dto.staff.StaffDRO;
import com.zmn.mcc.common.dto.staff.StaffQueryDIO;
import com.zmn.mcc.dubbo.interfaces.staff.StaffListRemoteService;
import com.zmn.oms.business.interfaces.baidumap.BaiduMapBService;
import com.zmn.oms.business.interfaces.callinfo.CallInfoBService;
import com.zmn.oms.business.interfaces.messageV1.common.MessageSendBaseService;
import com.zmn.oms.common.constant.OrderConsts;
import com.zmn.oms.common.constant.RedisKeyConsts;
import com.zmn.oms.common.dto.ResultDTO;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.model.bo.order.OrderBO;
import com.zmn.oms.model.dto.baidumap.LngLatLocation;
import com.zmn.oms.model.dto.messageV1.SmsMessageDTO;
import com.zmn.oms.model.dto.order.proxy.CreateOrderDTO;
import com.zmn.oms.model.dto.order.zmn.CheckManageCompanyDTO;
import com.zmn.oms.model.dto.product.OrderProductDTO;
import com.zmn.oms.model.entity.callinfo.CallClueInfo;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.model.vo.work.ZsOrderWorkVO;
import com.zmn.oms.third.eliao.EasyLiaoConsts;
import com.zmn.oms.third.eliao.api.EasyLiaoChatData;
import com.zmn.oms.third.eliao.api.EasyLiaoOrderData;
import com.zmn.oms.third.eliao.service.EasyLiaoService;
import com.zmn.oms.zmn.business.interfaces.proxy.ProxyOrderBService;
import com.zmn.oms.zmn.business.interfaces.work.OrderWorkAssignBService;
import com.zmn.oms.zmn.business.interfaces.work.ZsOrderWorkQueryBService;
import com.zmn.oms.zmn.business.interfaces.work.autoflow.WorkFlowContextBService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 12729易聊渠道接口实现类
 *
 * @author xiewenbing
 * @date 2020/11/20
 */
@Service
@Slf4j
public class EasyLiaoServiceImpl implements EasyLiaoService {

    @Reference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION , check = false)
    protected AreaListRemoteService areaListRemoteService;
    @Reference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION , check = false)
    private ChannelListRemoteService channelListRemoteService;
    @Reference(version = com.zmn.mcc.dubbo.dto.DubboConsts.INTERFACE_VERSION, check = false)
    protected StaffListRemoteService staffListRemoteService;

    @Autowired
    protected ZsOrderWorkQueryBService zsOrderWorkQueryBService;
    @Autowired
    protected ProxyOrderBService proxyOrderBService;
    @Autowired
    protected WorkFlowContextBService workFlowContextBService;
    @Autowired
    protected OrderWorkAssignBService orderWorkAssignBService;

    @Autowired
    private BaiduMapBService baiduMapBService;

    @Autowired
    private CallInfoBService callInfoBService;

    @Autowired
    private MessageSendBaseService messageSendBaseService;

    @Resource
    private RedisManager redisManager;

    /**
     * 创建订单
     *
     * @param paramOrder
     * @throws OmsBaseException
     */
    @Override
    public void createOrder(String paramOrder) throws OmsBaseException {

        if (!EasyLiaoConsts.POWER_ON) {
            throw new OmsBaseException("接口暂不支持");
        }

        if (StringUtil.isBlank(paramOrder)) {
            throw new OmsBaseException("参数不能为空");
        }

        // 解析数据
        EasyLiaoOrderData easyLiaoOrderData;
        try {
            easyLiaoOrderData =JSON.parseObject(paramOrder, EasyLiaoOrderData.class);
        } catch (Exception exception) {
            throw new OmsBaseException("数据解析失败");
        }

        // 公司id判断
        if (!Objects.equals(easyLiaoOrderData.getCompanyId(),String.valueOf(EasyLiaoConsts.COMPANY_ID))) {
            log.info("【{}】订单信息不为啄木鸟公司设置信息，不处理，公司ID【{}】",EasyLiaoConsts.CHANNEL_NAME,easyLiaoOrderData.getCompanyId());
            throw new OmsBaseException("公司ID不正确");
        }

        // 判断订单是否需要录入
        if (StringUtil.isBlank(easyLiaoOrderData.getRemark()) ||
                !Objects.equals(easyLiaoOrderData.getRemark(), EasyLiaoConsts.CREATE_ORDER_REMARK)) {
            throw new OmsBaseException("不为录入");
        }

        /*
        // 读取产品信息
        if (StringUtil.isBlank(easyLiaoOrderData.getProduct()) || easyLiaoOrderData.getProduct().indexOf('(') < 0 )  {
            log.info("【{}】订单产品信息为空/错误，无法录入",EasyLiaoConsts.CHANNEL_NAME);
            return;
        }
        */

        // 故障信息判断
        if (StringUtil.isBlank(easyLiaoOrderData.getCustomerRemark())) {
            log.info("【{}】故障信息为空，无法录入 - 【{}】",EasyLiaoConsts.CHANNEL_NAME, paramOrder);
            throw new OmsBaseException("无故障信息");
        }

        // 读取联系方式
        if (StringUtil.isBlank(easyLiaoOrderData.getMobile())) {
            log.info("【{}】手机号码为空，无法录入 - 【{}】",EasyLiaoConsts.CHANNEL_NAME, paramOrder);
            throw new OmsBaseException("手机号码不能为空");
        }

        // 读取渠道id
        if (StringUtil.isBlank(easyLiaoOrderData.getChannel()))  {
            log.info("【{}】订单渠道信息为空，无法录入 - 【{}】",EasyLiaoConsts.CHANNEL_NAME, paramOrder);
            throw new OmsBaseException("渠道获取失败");
        }

        Integer channelId = this.getIntegerInBrackets(easyLiaoOrderData.getChannel());
        if (NumberUtil.isNullOrZero(channelId)) {
            log.info("【{}】解析渠道信息失败，无法录入 - 【{}】",EasyLiaoConsts.CHANNEL_NAME, paramOrder);
            throw new OmsBaseException("渠道获取失败");
        }

        // 查询和验证渠道信息
        ChannelQuery channelQuery = new ChannelQuery();
        channelQuery.setPlat(GlobalConsts.PLAT_MARK_ZMN);
        channelQuery.setChannelId(channelId);

        ResponseDTO<List<ChannelDRO>> responseChannelDROListDTO =  channelListRemoteService.listByQuery(channelQuery);
        if (!responseChannelDROListDTO.isSuccess() || Objects.isNull(responseChannelDROListDTO.getData()) ||
                CollectionUtils.isEmpty(responseChannelDROListDTO.getData())) {
            log.info("【{}】订单渠道【{}】查询失败，无法录入 - 【{}】",EasyLiaoConsts.CHANNEL_NAME,easyLiaoOrderData.getChannel(), paramOrder);
            throw new OmsBaseException("渠道获取失败");
        }

        channelId = responseChannelDROListDTO.getData().get(0).getChannelId();
        String channelName = responseChannelDROListDTO.getData().get(0).getName();

        // 判断订单信息是否为重复单
        ZsOrderWorkVO orderWorkVO = zsOrderWorkQueryBService.findOrderWorkByOuterId(easyLiaoOrderData.getChatId(),channelId);
        if (Objects.nonNull(orderWorkVO)) {
            log.info("【{}】订单信息已经录入，orderId【{}】，线索【{}】",EasyLiaoConsts.CHANNEL_NAME,orderWorkVO.getOrderId(), paramOrder);
            throw new OmsBaseException("重复订单");
        }

        // 查询redis
        String redisKey = String.format(RedisKeyConsts.EASYLIAO_PULL_ORDER_REDIS_KEY,easyLiaoOrderData.getChatId());
        if (StringUtil.isNotBlank(redisManager.get(redisKey))) {
            log.info("【{}】订单信息已经录入中，chatId【{}】,线索【{}】",EasyLiaoConsts.CHANNEL_NAME,easyLiaoOrderData.getChatId(), paramOrder);
            throw new OmsBaseException("重复订单");
        }

        log.info("【{}】录入订单，【{}】", EasyLiaoConsts.CHANNEL_NAME, paramOrder);

        // 保存到redis
        JSONObject jsonObject = JSON.parseObject(paramOrder);
        jsonObject.put("currentChatJsonDetail","");
        redisManager.setex(redisKey,jsonObject.toJSONString(),300);

        // 生成创建订单的数据
        CreateOrderDTO createOrderDTO;
        try {
            createOrderDTO = buildCreateOrderDTO(easyLiaoOrderData);
        } catch(OmsBaseException e) {

            log.info("【{}】生成创建订单信息异常-【{}】", EasyLiaoConsts.CHANNEL_NAME, e.getMessage());

            // 删除redis
            redisManager.del(redisKey);
            throw e;
        }

        createOrderDTO.setChannelId(channelId);

        // 检测是否超区
        if (!this.checkServiceCapacityAndArea(createOrderDTO)) {

            log.info("【{}】保存订单失败，超出服务范围", EasyLiaoConsts.CHANNEL_NAME);

            this.pullCallInfo(createOrderDTO, channelName);
            this.sendUserSmsMessage(channelId, easyLiaoOrderData);

            // 删除redis
            redisManager.del(redisKey);

            throw new OmsBaseException("超出服务范围");
        }

        boolean result = this.doCreateOrder(createOrderDTO);

        // 此时不能删除，如果此时有订单数据进入，ES未同步，有可能导致订单重复录入
        // redisManager.del(redisKey);

        if (!result) {
            throw new OmsBaseException("创建订单失败");
        }
    }

    /**
     * 创建订单
     * @param createOrderDTO
     * @return
     */
    protected boolean doCreateOrder(CreateOrderDTO createOrderDTO) {

        if (Objects.isNull(createOrderDTO)) {
            return false;
        }

        try {

            // 创建订单
            OrderBO orderBO = proxyOrderBService.createOrder(createOrderDTO);
            OrderWork orderWork = orderBO.getOrderWork();

            log.info("【{}】保存订单成功 OrderId:[{}]", EasyLiaoConsts.CHANNEL_NAME, orderWork.getOrderId());

            // 工单自动流转
            workFlowContextBService.asyncAutoFlow(orderWork.getOrderId(),orderWork.getWorkId());

            return true;
        } catch (OmsBaseException omsBaseException) {
            log.info("【{}】保存订单异常，参数【{}】 OmsBaseException【{}】 ", EasyLiaoConsts.CHANNEL_NAME,
                    createOrderDTO.toString(),omsBaseException.getMessage());
        } catch (Exception exception) {
            log.info("【{}】保存订单失败，参数【{}】 Exception【{}】 ", EasyLiaoConsts.CHANNEL_NAME,
                    createOrderDTO.toString(),exception.getMessage());
        }

        return false;
    }

    /**
     * 生成创建订单的参数
     *
     * @param easyLiaoOrderData
     * @return
     */
    protected CreateOrderDTO buildCreateOrderDTO(EasyLiaoOrderData easyLiaoOrderData) throws OmsBaseException{

        CreateOrderDTO createOrderDTO = new CreateOrderDTO();
        String chatContent = this.getChatContent(easyLiaoOrderData);
        easyLiaoOrderData.setCurrentChatJsonDetail(null);

        if (StringUtil.isNotBlank(easyLiaoOrderData.getRequestId())) {
            createOrderDTO.setRequestId(easyLiaoOrderData.getRequestId());
        }

        // 渠道信息
        createOrderDTO.setOuterId(easyLiaoOrderData.getChatId());
        createOrderDTO.setOuterData(JSON.toJSONString(easyLiaoOrderData));
        createOrderDTO.setChannelId(EasyLiaoConsts.CHANNEL_ID);

        // 联系人信息
        createOrderDTO.setContactName(easyLiaoOrderData.getName());
        createOrderDTO.setTelephone(easyLiaoOrderData.getMobile());
        createOrderDTO.setTelephone2(easyLiaoOrderData.getTel());

        // 来源渠道  2021.01.18
        Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");  //用来判断字段是否为数字，防止异常
        if (StringUtil.isNotBlank(easyLiaoOrderData.getSourceChannel()) &&
                pattern.matcher(easyLiaoOrderData.getSourceChannel()).matches()) {
            createOrderDTO.setSourceChannelId(Integer.valueOf(easyLiaoOrderData.getSourceChannel()));
        }

        // 性别
        Integer sex = GlobalDict.GENDER_NO;
        if (Objects.equals(easyLiaoOrderData.getSex(),"男")) {
            sex = GlobalDict.GENDER_MAN;
        } else if (Objects.equals(easyLiaoOrderData.getSex(),"女")) {
            sex = GlobalDict.GENDER_WOMAN;
        }
        createOrderDTO.setGender(sex);

        // 预约时间
        createOrderDTO.setDutyTime(null);

        // 平台、操作者等信息
        createOrderDTO.setBizType(com.zmn.consts.GlobalConsts.BIZ_TYPE_C);
        createOrderDTO.setPlat(GlobalConsts.PLAT_MARK_ZMN);
        createOrderDTO.setDisableDiscard(GlobalConsts.NO);

        // 操作者
        this.fillOperatorCreateOrderDTO(createOrderDTO,easyLiaoOrderData);

        // 操作者类型与输入类型
        createOrderDTO.setOperatorType(GlobalConsts.OPERATE_USER_TYPE_STAFF);
        createOrderDTO.setInputType(OrderConsts.ORDER_INPUT_TYPE_MANUAL);
        createOrderDTO.setProxyFromType(
                Objects.equals(GlobalConsts.YES, easyLiaoOrderData.getFromXiaoZhuoAI())
                        ? GateTypeConsts.GATE_PLAT_XIAOZHUO_AI
                        : GateTypeConsts.GATE_PLAT_CHAT
        );

        // 操作日志
        createOrderDTO.setOperatorLogRemark(String.format("<br/>会话id：%s；渠道信息：[%s]；产品信息：[%s]；地址信息：[%s]；对话内容：<br/> %s <br/>",
                easyLiaoOrderData.getChatId(), Optional.ofNullable(easyLiaoOrderData.getChannel()).orElse(""),
                Optional.ofNullable(easyLiaoOrderData.getProduct()).orElse(""),
                Optional.ofNullable(easyLiaoOrderData.getAddress()).orElse(""),chatContent));

        // 地址信息
        this.fillAddress(createOrderDTO,easyLiaoOrderData);

        // 获取ProductId
        Integer productId = this.getIntegerInBrackets(easyLiaoOrderData.getProduct());

        // 产品信息
        OrderProductDTO orderProduct = new OrderProductDTO();
        orderProduct.setProductId(NumberUtil.isNotNullOrZero(productId) ? productId : OrderConsts.CHANNEL_DISABLED_PRODUCT_ID);
        orderProduct.setNumber(1);
        orderProduct.setRemark(Optional.ofNullable(easyLiaoOrderData.getCustomerRemark()).orElse(""));

        List<OrderProductDTO> list = new LinkedList<>();
        list.add(orderProduct);
        createOrderDTO.setOrderProductList(list);

        return createOrderDTO;
    }

    /**
     * 填充创建订单信息中的操作员信息
     *
     * @param createOrderDTO
     * @param easyLiaoOrderData
     */
    private void fillOperatorCreateOrderDTO(CreateOrderDTO createOrderDTO,EasyLiaoOrderData easyLiaoOrderData){

        if (Objects.isNull(createOrderDTO) || Objects.isNull(easyLiaoOrderData)) {
            return;
        }

        createOrderDTO.setOperator("客服人员");
        createOrderDTO.setOperatorId(0L);

        String operatorName = Optional.ofNullable(easyLiaoOrderData.getCreateUserRealName()).orElse(easyLiaoOrderData.getUserRealName());
        if (StringUtil.isBlank(operatorName) || operatorName.charAt(0) == '$') {
            return;
        }

        String operator = operatorName;
        if (operatorName.lastIndexOf('(') >= 0) {
            operator = operatorName.substring(0,operatorName.lastIndexOf('('));
        }

        createOrderDTO.setOperator(operator);

        //解析 格式为 姓名(id)
        Integer operatorId = this.getIntegerInBrackets(operatorName);
        if (NumberUtil.isNotNullOrZero(operatorId)) {
            createOrderDTO.setOperatorId(Long.valueOf(operatorId));
            return;
        }

        // 查找id
        StaffQueryDIO staffQueryDIO = new StaffQueryDIO();
        staffQueryDIO.setRealName(operator);
        staffQueryDIO.setPlat(GlobalConsts.PLAT_MARK_ZMN);
        ResponseDTO<List<StaffDRO>> staffListResponseDTO = staffListRemoteService.listStaffByQueryDIO(staffQueryDIO);
        if (!staffListResponseDTO.isSuccess() || CollectionUtils.isEmpty(staffListResponseDTO.getData())) {
            return;
        }

        List<StaffDRO> staffDROList = staffListResponseDTO.getData();
        if (staffDROList.size() == 1) {
            createOrderDTO.setOperatorId(staffDROList.get(0).getStaffId().longValue());
            return;
        }

        for (StaffDRO staffDRO : staffDROList) {

            // 二级部门为网络客服组
            if (staffDRO.getDeptTwoId()==2041) {
                createOrderDTO.setOperatorId(staffDRO.getStaffId().longValue());
                return;
            }
        }

        createOrderDTO.setOperatorId(staffDROList.get(0).getStaffId().longValue());
    }

    /**
     * 填充创建订单信息中的地址信息
     *
     * @param createOrderDTO
     * @param easyLiaoOrderData
     */
    private void fillAddress(CreateOrderDTO createOrderDTO,EasyLiaoOrderData easyLiaoOrderData) throws OmsBaseException{

        if (Objects.isNull(createOrderDTO) || Objects.isNull(easyLiaoOrderData)) {
            return;
        }

        // 生成地址信息
        String detailAddress = easyLiaoOrderData.getAddress();
        if (StringUtil.isNotBlank(detailAddress)) {

            // 除字符串中的空格、回车、换行符、制表符
            Pattern p = Pattern.compile("\\s*|\t|\r|\n");
            Matcher m = p.matcher(detailAddress);
            detailAddress = m.replaceAll("");
        }

        // 合成具体地址
        String address = easyLiaoOrderData.getProvince() + easyLiaoOrderData.getCity() + detailAddress;
        if (StringUtil.isBlank(address)) {
            throw new OmsBaseException("地址信息不能为空");
        }

        // 模糊匹配 - 设置区，街道信息
        String region =  easyLiaoOrderData.getCity();
        LngLatLocation areaLocation = baiduMapBService.suggestion(region,detailAddress);
        if (Objects.nonNull(areaLocation)) {
            createOrderDTO.setStreet(areaLocation.getAddress());
        } else {
            log.info("【{}】匹配查找失败，【{}】【{}】",EasyLiaoConsts.CHANNEL_NAME, region, detailAddress);
        }

        // 根据详细地址查询经纬度
        LngLatLocation detailLocation = baiduMapBService.location(address);
        if (Objects.isNull(detailLocation)) {
            log.info("【{}】地址信息解析失败，【{}】",EasyLiaoConsts.CHANNEL_NAME,address);

            // 定位和匹配都失败
            if (Objects.isNull(areaLocation)) {
                throw new OmsBaseException("地址解析失败");
            }
        }

        // 城市区域查找
        LngLatLocation location = Objects.nonNull(detailLocation) ? detailLocation : areaLocation;
        ResponseDTO<AreaDRO> areaResponse = areaListRemoteService.getAreaByLatAndLng(Double.valueOf(location.getLng()),
                Double.valueOf(location.getLat()));
        if (!areaResponse.isSuccess() || Objects.isNull(areaResponse) || Objects.isNull(areaResponse.getData()) ||
                Objects.isNull(areaResponse.getData().getParentId()) || Objects.isNull(areaResponse.getData().getLongitude()) ||
                Objects.isNull(areaResponse.getData().getLatitude())) {

            log.info("【{}】城市区域信息查询失败，【{}】【{}】【{}】",EasyLiaoConsts.CHANNEL_NAME, address, JSON.toJSONString(location), areaResponse);
            throw new OmsBaseException("地址解析失败");
        }

        Integer cityId = Integer.valueOf(areaResponse.getData().getParentId());
        Double longitude = Double.valueOf(location.getLng());
        Double latitude = Double.valueOf(location.getLat());
        createOrderDTO.setLongitude(longitude);
        createOrderDTO.setLatitude(latitude);
        createOrderDTO.setCityId(cityId);
        createOrderDTO.setAddress(detailAddress);

        /*
        createOrderDTO.setCityId(cityId);
        createOrderDTO.setAddress(address);
        createOrderDTO.setStreet("");

        boolean rightAddress = false;
        boolean areaLatLng = true;
        Integer areaCode = 0;

        BaiduMapUtil.Location addressLocation = null;
        if (!StringUtil.isBlank(address) && address.compareTo("--") !=0) {
            // 获取经纬度
            addressLocation = BaiduMapUtil.locatin(address);
            if (Objects.nonNull(addressLocation)) {
                rightAddress = true;
            }
        }

        if (!rightAddress) {
            // 根据手机号查找
            String mobile = easyLiaoOrderData.getMobile();
            log.info("【{}】通过手机号查找归属地(PhoneCityUtils.cityOfMobilePhone)，入参【{}】",EasyLiaoConsts.CHANNEL_NAME,mobile);
            PhoneCity phoneCity = PhoneCityUtils.getInstance().cityOfMobilePhone(mobile);
            log.info("【{}】通过手机号查找归属地(PhoneCityUtils.cityOfMobilePhone)，出参[{}][{}][{}]",EasyLiaoConsts.CHANNEL_NAME,
                    Optional.ofNullable(phoneCity.getProvinceName()).orElse(""),
                    Optional.ofNullable(phoneCity.getCityName()).orElse(""),
                    Optional.ofNullable(phoneCity.getCityId()).orElse(""));

            if (Objects.isNull(phoneCity)) {
                return;
            }

            StringBuilder sbAddress = new StringBuilder();
            String provinceName = phoneCity.getProvinceName();
            String cityName = phoneCity.getCityName();

            String[] noProvinceAdd={"北京","天津","上海","重庆","内蒙古","广西","西藏","宁夏","新疆","香港","澳门"};

            if (StringUtil.isNotBlank(provinceName)) {
                sbAddress.append(provinceName);
                if (provinceName.substring(provinceName.length() - 1).compareToIgnoreCase("省") != 0 &&
                        !Arrays.asList(noProvinceAdd).contains(provinceName)) {
                    sbAddress.append("省");
                }
            }

            if (StringUtil.isNotBlank(cityName)) {
                sbAddress.append(cityName);
                if (provinceName.substring(cityName.length()-1).compareToIgnoreCase("市") != 0) {
                    sbAddress.append("市");
                }
            }

            address = sbAddress.toString();

            do {

                areaLatLng = false;
                if (StringUtil.isBlank(address)) {
                    break;
                }

                // 获取经纬度
                addressLocation = BaiduMapUtil.locatin(address);
                if (Objects.isNull(addressLocation)) {
                    break;
                }

                areaLatLng = true;
            }while(false);

            // 省市信息和城市id都不存在
            if (!areaLatLng && StringUtil.isBlank(phoneCity.getCityId())) {
                return;
            }

            areaCode = Integer.valueOf(phoneCity.getCityId());
            createOrderDTO.setAddress("");
        }

        // 查找
        ResponseDTO<AreaDRO> areaResponse = null;

        if (areaLatLng) {
            areaResponse = areaListRemoteService.getByLatAndLng(Double.valueOf(addressLocation.getLng()),
                    Double.valueOf(addressLocation.getLat()));
        } else {
            areaResponse = areaListRemoteService.getByCode(areaCode);
        }

        if (Objects.isNull(areaResponse) || Objects.isNull(areaResponse.getData())) {
            return;
        }

        cityId = areaLatLng ? Integer.valueOf(areaResponse.getData().getParentId()) : areaResponse.getData().getCityId();

        // 获取经纬度
        Double longitude = Double.valueOf(areaResponse.getData().getLongitude());
        Double latitude = Double.valueOf(areaResponse.getData().getLatitude());
        createOrderDTO.setLongitude(longitude);
        createOrderDTO.setLatitude(latitude);
        createOrderDTO.setCityId(cityId);
        */
    }

    /**
     * 提取括号内的整数
     * @param content
     * @return
     */
    private static Integer getIntegerInBrackets(String content) {

        // 参数判断
        if (StringUtil.isBlank(content)) {
            return null;
        }

        // 根据正则提取渠道id
        Matcher matcher[] = {
                Pattern.compile("(?<=\\（)(\\d*)(?=\\）)").matcher(content),
                Pattern.compile("(?<=\\（)(\\d*)(?=\\))").matcher(content),
                Pattern.compile("(?<=\\()(\\d*)(?=\\）)").matcher(content),
                Pattern.compile("(?<=\\()(\\d*)(?=\\))").matcher(content)
        };

        for (int i = 0; i < 4; i++) {

            int groupCount = matcher[i].groupCount();
            if ( groupCount <= 0) {
                continue;
            }

            while(matcher[i].find()) {
                String cid = matcher[i].group();
                if (StringUtil.isBlank(cid)) {
                    continue;
                }

                Integer id = Integer.valueOf(cid);
                if (NumberUtil.isNotNullOrZero(id)) {
                    return id;
                }
            }
        }

        return null;
    }

    /**
     * 检测是否查出服务区
     * @param createOrderDTO
     * @return
     */
    private boolean checkServiceCapacityAndArea(CreateOrderDTO createOrderDTO) throws OmsBaseException {

        // 检测服务能力
        CheckManageCompanyDTO checkManageCompanyDTO = new CheckManageCompanyDTO();
        checkManageCompanyDTO.setPlatWork(createOrderDTO.getPlat());
        checkManageCompanyDTO.setBizType(createOrderDTO.getBizType());
        checkManageCompanyDTO.setType(OrderConsts.ORDER_TYPE_NEW);
        checkManageCompanyDTO.setChannelId(createOrderDTO.getChannelId());
        checkManageCompanyDTO.setCityId(createOrderDTO.getCityId());
        checkManageCompanyDTO.setProductId(createOrderDTO.getOrderProductList().get(0).getProductId());
        checkManageCompanyDTO.setLongitude(createOrderDTO.getLongitude());
        checkManageCompanyDTO.setLatitude(createOrderDTO.getLatitude());

        // 检测
        return orderWorkAssignBService.checkServiceCapacity(checkManageCompanyDTO);
    }

    /**
     * 推送线索给呼叫系统
     *
     * @param createOrderDTO
     * @param channelName
     */
    private void pullCallInfo(CreateOrderDTO createOrderDTO, String channelName) {

        if (Objects.isNull(createOrderDTO)) {
            return;
        }

        // 生成线索信息
        CallClueInfo callClueInfo = new CallClueInfo();
        callClueInfo.setChannelId(createOrderDTO.getChannelId());
        callClueInfo.setChannelName(channelName);
        callClueInfo.setCustomerPhone(createOrderDTO.getTelephone());
        callClueInfo.setCustomerName(createOrderDTO.getContactName());
        callClueInfo.setCityId(createOrderDTO.getCityId());
        callClueInfo.setAddress(createOrderDTO.getAddress());
        callClueInfo.setRemark("不在服务区");
        callClueInfo.setAutomatic(2);
        callClueInfo.setOperator(createOrderDTO.getOperator());

        ResultDTO resultDTO = callInfoBService.insertCallClue(callClueInfo);
        if (!resultDTO.isStatusBool()) {
            log.info("【{}】超区线索录入呼叫系统失败-【{}】", EasyLiaoConsts.CHANNEL_NAME, resultDTO.getMessage());
        }
    }

    /**
     * 发送超出服务短消息给用户
     * @param channelId
     * @param easyLiaoOrderData
     */
    private void sendUserSmsMessage(Integer channelId, EasyLiaoOrderData easyLiaoOrderData) {

        String redisKey = String.format(RedisKeyConsts.EASYLIAO_SEND_SMS_MESSAGE_KEY,easyLiaoOrderData.getChatId());
        String redisValue = redisManager.get(redisKey);
        String telephone = easyLiaoOrderData.getMobile();

        if (StringUtil.isNotBlank(redisValue) && Objects.equals(redisValue,telephone)) {
            log.info("【{}】 已经发送短信给用户【{}】，不需要重发", EasyLiaoConsts.CHANNEL_NAME, telephone);
            return;
        }

        // 参数
        SmsMessageDTO smsMessageDTO = SmsMessageDTO.builder()
                .mobile(telephone)
                .ruleId(EasyLiaoConsts.OUT_SERVICE_MESSAGE_RULE_ID)
                .channelId(String.valueOf(channelId))
                .build();

        // 产品名称
        String product = easyLiaoOrderData.getProduct();
        String productName = product;
        do {
            if (StringUtil.isBlank(product)) {
                break;
            }

            Integer productId = this.getIntegerInBrackets(product);
            if (NumberUtil.isNullOrZero(productId)) {
                break;
            }

            productName = product.substring(0, product.indexOf(String.valueOf(productId)) - 2);

        } while (false);

        if (StringUtil.isBlank(productName)) {
            productName = "啄木鸟维修";
        }

        Map<String, String> param = new HashMap<>(1);
        param.put("product_name", productName);

        smsMessageDTO.setParams(JSON.toJSONString(param));

        if (!messageSendBaseService.sendTextMessage(smsMessageDTO)) {
            log.info("【{}】 发送短信给用户【{}】失败", EasyLiaoConsts.CHANNEL_NAME, telephone);
            return;
        }

        // 缓存短信发送数据
        redisManager.setex(redisKey, telephone, 24 * 60 * 60);
    }

    /**
     * 解析聊天内容，并合成显示
     * @param easyLiaoOrderData
     * @return
     */
    private String getChatContent(EasyLiaoOrderData easyLiaoOrderData) {

        if (Objects.isNull(easyLiaoOrderData) || StringUtil.isBlank(easyLiaoOrderData.getCurrentChatJsonDetail())) {
            return "";
        }

        List<EasyLiaoChatData> chatDataList = null;
        try {
            chatDataList = JSON.parseArray(easyLiaoOrderData.getCurrentChatJsonDetail(),EasyLiaoChatData.class);
        } catch (Exception e) {
            log.info("【{}】解析聊天内容异常【{}】",EasyLiaoConsts.CHANNEL_NAME,easyLiaoOrderData.getCurrentChatJsonDetail());
            return "";
        }

        if (CollectionUtils.isEmpty(chatDataList)) {
            return "";
        }

        StringBuilder sbChatContent = new StringBuilder();
        for (EasyLiaoChatData chatData : chatDataList) {

            if (chatData.getSenderType() == 0) {
                sbChatContent.append(chatData.getFromId());
            } else {
                sbChatContent.append(easyLiaoOrderData.getName());
            }

            sbChatContent.append(" (").append(chatData.getCreateTime()).append(") <br/> ").append(chatData.getMessage()).append("<br/><br/>");
        }

        return sbChatContent.toString();
    }

    public static void main(String[] args) {

        String mobile = "13456268095";

        log.info("【{}】通过手机号查找归属地(PhoneCityUtils.cityOfMobilePhone)，入参【{}】",EasyLiaoConsts.CHANNEL_NAME,mobile);
        PhoneCity phoneCity = PhoneCityUtils.getInstance().cityOfMobilePhone(mobile);
        log.info("【{}】通过手机号查找归属地(PhoneCityUtils.cityOfMobilePhone)，出参[{}][{}][{}]",EasyLiaoConsts.CHANNEL_NAME,
                Optional.ofNullable(phoneCity.getProvinceName()).orElse(""),
                Optional.ofNullable(phoneCity.getCityName()).orElse(""),
                Optional.ofNullable(phoneCity.getCityId()).orElse(""));

        StringBuilder sbAddress = new StringBuilder();
        String provinceName = phoneCity.getProvinceName();
        String cityName = phoneCity.getCityName();

        String[] noProvinceAdd={"北京","天津","上海","重庆","内蒙古","广西","西藏","宁夏","新疆","香港","澳门"};

        if (StringUtil.isNotBlank(provinceName)) {
            sbAddress.append(provinceName);
            if (provinceName.substring(provinceName.length() - 1).compareToIgnoreCase("省") != 0 &&
                    !Arrays.asList(noProvinceAdd).contains(provinceName)) {
                sbAddress.append("省");
            }
        }

        if (StringUtil.isNotBlank(cityName)) {
            sbAddress.append(cityName);
            if (provinceName.substring(cityName.length()-1).compareToIgnoreCase("市") != 0) {
                sbAddress.append("市");
            }
        }

        System.out.println(sbAddress);
    }
}